package com.zeny.express.framework.webapp.action;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.codehaus.jackson.type.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;

import com.opensymphony.xwork2.ActionInvocation;
import com.zeny.express.framework.core.domain.Page;
import com.zeny.express.framework.shared.serializer.JsonSerializer;
import com.zeny.express.framework.webapp.domain.ExportParams;
import com.zeny.express.framework.webapp.domain.PageParams;
import com.zeny.express.framework.webapp.excel.ExcelExporter;
import com.zeny.express.framework.webapp.excel.GridModel;

/**
 * Grid Action 提供基本查询服务
 * 
 * @author zhuwei
 * @date 2013年8月28日 上午11:01:50
 */
@SuppressWarnings("serial")
public abstract class BaseGridAction extends BaseAction {

	private static List<String> PAGE_PARAMS = Arrays.asList(new String[] {
			"pageParams.currentPage", "pageParams.pageSize",
			"pageParams.sortName", "pageParams.sortOrder", "pageParams.search",
			"pageParams.random", "isPageCache", "loadPageCache" });

	private static JsonSerializer<List<GridModel>> gridModelSerializer = new JsonSerializer<List<GridModel>>(false, 
			new TypeReference<List<GridModel>>() {});
	
	@Autowired
	protected ExcelExporter excelExporter;
	
	/**
	 * 翻页查询参数
	 */
	protected PageParams pageParams = new PageParams();

	/**
	 * 查询参数
	 */
	protected Map<String, Object> searchParams = new HashMap<String, Object>();

	/**
	 * 导出参数
	 */
	protected ExportParams exportParams = new ExportParams();

	/**
	 * 查询翻页结果集
	 */
	protected Page<?> page;

	/**
	 * 是否从缓存加载页面
	 */
	protected Boolean loadPageCache;

	/**
	 * 列表页面
	 * 
	 * @author zhuwei
	 * @date 2013年8月28日 上午11:02:35
	 * @return 返回tiles页面
	 */
	public abstract String list();

	/**
	 * 翻页查询
	 * 
	 * @author zhuwei
	 * @date 2013年8月28日 上午11:05:46
	 * @return 返回json数据
	 */
	public abstract String search();

	/**
	 * 导出数据
	 * 
	 * @author zhuwei
	 * @date 2013年8月28日 上午11:11:40
	 * @return
	 */
	public abstract String export();

	@Override
	@SuppressWarnings("rawtypes")
	public void beforeInvoke(ActionInvocation invocation) {

		super.beforeInvoke(invocation);

		String method = invocation.getProxy().getMethod();

		initSearchParams();

		// 翻页查询预处理
		if (StringUtils.startsWith(method, "search")) {

			this.page = new Page(pageParams.getCurrentPage(),
					pageParams.getPageSize());

			initPageParams();
		}
		// 导出预处理
		else if (StringUtils.startsWith(method, "export")) {

			this.page = new Page(Page.PAGE_BEGIN, Integer.MAX_VALUE);
			this.page.setTotalCounted(false);

			initPageParams();

			exportParams.setPage(page);
			
			exportParams.getColModel();
			
			List<GridModel> colModelList = gridModelSerializer.deserialize(exportParams.getColModel().getBytes());
			exportParams.setColModelList(colModelList);
			
		}

	}

	@Override
	public void afterInvoke(ActionInvocation invocation) {

		super.afterInvoke(invocation);

	}

	@SuppressWarnings("unchecked")
	private void initSearchParams() {
		Map<String, String[]> parameters = ServletActionContext.getRequest()
				.getParameterMap();
		Set<String> keys = parameters.keySet();
		for (String key : keys) {

			if (PAGE_PARAMS.contains(key)) {
				continue;
			}

			String[] values = parameters.get(key);
			if (values != null && values.length == 1) {
				searchParams.put(key, values[0]);
			} else {
				searchParams.put(key, values);
			}

		}
	}

	private void initPageParams() {

		if (StringUtils.isBlank(pageParams.getSortName())) {
			return;
		}

		String sortNames = pageParams.getSortName() + " "
				+ pageParams.getSortOrder();

		String[] fields = sortNames.split(",");

		for (String field : fields) {
			String[] array = field.split(" ");
			page.addOrder(array[0], array.length > 1 ? array[1] : null);
		}
	}

	/**
	 * 设置翻页返回数据
	 * 
	 * @author zhuwei
	 * @date 2013年11月3日 下午8:14:38
	 * @param page
	 */
	protected void setResult(Page<?> page) {
		// result.put("pageSize", page.getPageSize());
		result.put("currentPage", page.getCurrentPage());
		result.put("totalPages", page.getTotalPages());
		result.put("totalRows", page.getTotalRows());
		result.put("rows", page.getRows());

		result.put("userdata", page.getAggregationResult());
	}

	/**
	 * 同步导出Excel文件
	 * 
	 * @author zhuwei
	 * @date 2013年11月14日 下午1:09:42
	 * @return
	 * @throws FileNotFoundException 
	 */
	public InputStream getExportFile() throws FileNotFoundException {
		
		return new FileInputStream(exportParams.getFile());
	}

	/**
	 * @return exportParams
	 */
	public ExportParams getExportParams() {
		return exportParams;
	}

	/**
	 * @param exportParams
	 */
	public void setExportParams(ExportParams exportParams) {
		this.exportParams = exportParams;
	}

	/**
	 * @return pageParams
	 */
	public PageParams getPageParams() {
		return pageParams;
	}

	/**
	 * @param pageParams
	 */
	public void setPageParams(PageParams pageParams) {
		this.pageParams = pageParams;
	}

	/**
	 * @param loadPageCache
	 */
	public void setLoadPageCache(Boolean loadPageCache) {
		this.loadPageCache = loadPageCache;
	}

}
